"""
HTML exporter for creating Reveal.js presentations.
"""

import json
from pathlib import Path
from typing import Dict, Any, Optional, List
from jinja2 import Template, Environment, FileSystemLoader

from ...parser.content_types import DocumentStructure, ContentType, AnimatedContent
from ...animation.engines.reveal_engine import RevealJSEngine
from ...utils.exceptions import MD2PPTError


class HTMLExporter:
    """Exports presentations to HTML format with Reveal.js."""
    
    def __init__(self, theme: str = "white", template_dir: Optional[str] = None):
        """Initialize HTML exporter."""
        self.theme = theme
        self.reveal_engine = RevealJSEngine()
        
        # Set up Jinja2 environment
        if template_dir:
            self.template_dir = Path(template_dir)
        else:
            # Use built-in templates
            self.template_dir = Path(__file__).parent.parent.parent / "animation" / "templates" / "reveal"
        
        self.jinja_env = Environment(
            loader=FileSystemLoader(str(self.template_dir)),
            autoescape=True
        )
    
    def export(self, doc_structure: DocumentStructure, 
               output_path: str, 
               config: Optional[Dict[str, Any]] = None) -> None:
        """
        Export document structure to HTML presentation.
        
        Args:
            doc_structure: Parsed document structure
            output_path: Output HTML file path
            config: Optional export configuration
        """
        # Load template
        template = self.jinja_env.get_template("base.html")
        
        # Generate slide content
        slides_html = self._generate_slides(doc_structure)
        
        # Collect animations for CSS generation
        animation_delays = self._collect_animation_delays(doc_structure)
        
        # Generate Reveal.js configuration
        reveal_config = self.reveal_engine.generate_reveal_config(config)
        
        # Template context
        context = {
            'title': doc_structure.title,
            'theme': self.theme,
            'content': slides_html,
            'reveal_config': reveal_config,
            'default_duration': 1.0,
            'default_easing': 'ease',
            'animation_delays': animation_delays
        }
        
        # Render HTML
        html_content = template.render(**context)
        
        # Write to file
        output_file = Path(output_path)
        output_file.parent.mkdir(parents=True, exist_ok=True)
        
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(html_content)
    
    def _generate_slides(self, doc_structure: DocumentStructure) -> str:
        """Generate HTML content for all slides."""
        slides = []
        
        for section in doc_structure.sections:
            # Collect animated content for this section
            animations = []
            for content_node in section.content:
                if content_node.type == ContentType.ANIMATED_CONTENT:
                    animations.append(content_node.data)
            
            # Generate slide HTML
            slide_html = self.reveal_engine.render_section(section, animations)
            slides.append(slide_html)
        
        return '\n'.join(slides)
    
    def _collect_animation_delays(self, doc_structure: DocumentStructure) -> List[tuple]:
        """Collect all animation delays for CSS generation."""
        delays = set()
        
        for section in doc_structure.sections:
            for content_node in section.content:
                if content_node.type == ContentType.ANIMATED_CONTENT:
                    animated_content = content_node.data
                    if animated_content.delay > 0:
                        delay_index = int(animated_content.delay * 10)
                        delays.add(delay_index)
        
        # Convert to sorted list of tuples for template
        return [(delay, f"fragment-{delay}") for delay in sorted(delays)]
    
    def get_supported_themes(self) -> List[str]:
        """Get list of supported Reveal.js themes."""
        return [
            'beige', 'black', 'blood', 'league', 'moon', 'night',
            'serif', 'simple', 'sky', 'solarized', 'white'
        ]
    
    def validate_theme(self, theme: str) -> bool:
        """Validate if theme is supported."""
        return theme in self.get_supported_themes()


class HTMLExportError(MD2PPTError):
    """Raised when HTML export fails."""
    pass